#include <math.h>
#include <allegro.h>

#define NUM 200

struct particle{
    double mass;
    double x, y;
    long oldX, oldY;
    long xp;
    long yp;
    double ax;
    double ay;
    double vx;
    double vy;
}p[NUM];

int CX, CY;

void resetparticle(int n);
void updateparticles();
void resetall();

void attract(struct particle *A, struct particle *B){
    double distance;
    double dist, distX, distY;
    double transX, transY;

    // Increasing position of velocity value;
    A->x += A->vx;
    A->y += A->vy;

    // calculate the vector distance between particles...
    distX = A->x - B->x;
    distY = A->y - B->y;
    dist = distX * distX + distY * distY; // Pytagoras for those who don't remember.
    if(dist != 0)
        distance = 1 / dist;
    else
        distance = 0;

    transX = distX * distance;
    transY = distY * distance;

    // Acceleration TIME :D
    A->ax = -1 * B->mass * transX;
    A->ay = -1 * B->mass * transY;

    // Increase velocity by acceleration value FULL SPEED CAPTAIN SPOCK
    A->vx += A->ax;
    A->vy += A->ay;

    A->xp = CX + A->x;
    A->yp = CY - A->y;

}

void update(){

    int n;
    int i;
    int blue,green,red,colour;

    red = rand() % 255;
    green = rand() % 255;
    blue = rand() % 255;
    colour = makecol(red,green,blue);

    for(n = 0;n < NUM; n++) // incase you're wondering, this is to erase old particles, not to be a total retard or anything ;)

    for(n = 0;n < NUM; n++){
        circlefill(screen, p[n].oldX, p[n].oldY,5,0);

        // GRAVITY BITCHES :D
        for(i=0; i <NUM; i++){
            if(i != n)
                attract(&p[n], &p[i]);
        }

        // reset particles in the case things are too far away
        if(p[n].xp < -1000 || p[n].xp > 1000 || p[n].yp < -1000 || p[n].yp > 1000)
            resetparticle(n);

        circlefill(screen, p[n].xp, p[n].yp, 4,colour); // :D

        p[n].oldX = p[n].xp;
        p[n].oldY = p[n].yp;
    }
    // This is the particle to be drawned, can't have it inside the big loop xD



    circlefill(screen, p[0].xp, p[0].yp,5,colour);
}

// RESET TIME!!!

void resetparticle(int n){
    p[n].mass = 0.001;
    p[n].ax = 0;
    p[n].ay = 0;
    p[n].xp = 0;
    p[n].yp = 0;
    p[n].x = rand() % SCREEN_W/4;
    p[n].y = rand() % SCREEN_H/4;
    p[n].vx = 0;
    p[n].vy = 0;
}

void resetall(){
    int n;
    CX = SCREEN_W / 2;
    CY = SCREEN_H / 2;

    for(n = 0; n<NUM; n++)
        resetparticle(n);
}

int main(void){

    int ret;

    // init allegro shizzles
    allegro_init();
    install_keyboard();
    install_timer();
    srand(time(NULL));

    // init video
    ret = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);

    if(ret != 0){
        allegro_message(allegro_error);
        return 1;
    }

    resetall();

    while(!key[KEY_ESC]){
        update();

        textprintf_ex(screen, font, 0,0,15,-1, "Particles!! :D - %dx%d - Press ESC to quit.", SCREEN_W, SCREEN_H);

    }

    allegro_exit();
    return 0;
}
END_OF_MAIN()
